#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <dbg/ptest.h>
// #include <dinfra/init_fin.h>
#include <dinfra/mpwf/wmsp.h>

#define POOL_SIZE (2 * 1024 * 1024)
static wmobj_t *testnode_list = NULL_PTR;
DEF_WMSP_OBJ_CACHED(testnode, &testnode_list, HDEF_CACHE_LINE_BYTES, POOL_SIZE)

DEF_SYSINIT(testnode)
#include <sys/mman.h>
int main(){
	int madv_ret = madvise(&testnode_wmsp_poolmem, POOL_SIZE, 14);
	if (madv_ret)
		fprintf(stderr, "madvise failed %d\n", madv_ret);

	printf("[%p, %p] size %lu\n", (void *)testnode_wmsp_poolmem, PTR_ARITH(testnode_wmsp_poolmem,+,POOL_SIZE), (size_t)POOL_SIZE);
	void *mem = testnode_palloc(1024 * 1024);
	assert(mem);
	// printf("%p\n", mem);
	mem = testnode_palloc(1024 * 1024 * 1024);
	assert(mem == NULL);
	mem = testnode_palloc(512 * 1024);
	assert(mem);
	// printf("%p\n", mem);
	void *mems[(POOL_SIZE - 1024 * 1024 - 512 * 1024)/HDEF_CACHE_LINE_BYTES];
	for (word_t idx = 0; idx < (POOL_SIZE - 1024 * 1024 - 512 * 1024)/HDEF_CACHE_LINE_BYTES; idx++){
		mems[idx] = testnode_cachealloc();
		assert(mems[idx]);
		// printf("%p\n", mems[idx]);
	}
	mem = testnode_cachealloc();
	// printf("%p\n", mem);
	assert(!mem);

	for (word_t idx = 0; idx < (POOL_SIZE - 1024 * 1024 - 512 * 1024)/HDEF_CACHE_LINE_BYTES; idx++){
		testnode_cachefree(mems[idx]);
	}

	mem = testnode_palloc(64);
	// printf("%p\n", mem);
	assert(!mem);

	for (word_t idx = 0; idx < (POOL_SIZE - 1024 * 1024 - 512 * 1024)/HDEF_CACHE_LINE_BYTES; idx++){
		mems[idx] = testnode_cachealloc();
		assert(mems[idx]);
		// printf("%p\n", mems[idx]);
	}

	mem = testnode_cachealloc();
	// printf("%p\n", mem);
	assert(!mem);
	for (word_t idx = 0; idx < (POOL_SIZE - 1024 * 1024 - 512 * 1024)/HDEF_CACHE_LINE_BYTES; idx++){
		testnode_cachefree(mems[idx]);
	}
	testnode_threadend();

	for (word_t idx = 0; idx < (POOL_SIZE - 1024 * 1024 - 512 * 1024)/HDEF_CACHE_LINE_BYTES; idx++){
		mems[idx] = testnode_cachealloc();
		assert(mems[idx]);
		// printf("%p\n", mems[idx]);
	}
	mem = testnode_cachealloc();
	// printf("%p\n", mem);
	assert(!mem);
}
